package com.mapperdb.helper;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.scripting.xmltags.MixedSqlNode;
import org.apache.ibatis.scripting.xmltags.SetSqlNode;
import org.apache.ibatis.scripting.xmltags.SqlNode;
import org.apache.ibatis.scripting.xmltags.StaticTextSqlNode;
import org.apache.ibatis.scripting.xmltags.TrimSqlNode;
import org.apache.ibatis.scripting.xmltags.WhereSqlNode;

import com.mapperdb.mapping.Result;

/**
 * Mapper SqlSource 提供类
 * @author Administrator
 *
 */
public class MapperProvider extends MapperTemplate {

	/**
	 * 查询
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode selectOne(MappedStatement ms) {
		return select(ms);
	}

	/**
	 * 查询
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode select(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//静态的sql部分:select column ... from table
		sqlNodes.add(new StaticTextSqlNode("SELECT " + resultEntity.getSelectColumns() + " FROM " + resultEntity.getTableName()));
		//将if添加到<where>
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), getAllIfColumnNode(resultEntity)));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 查询
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode selectByPrimaryKey(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//静态的sql部分:select column ... from table
		sqlNodes.add(new StaticTextSqlNode("SELECT " + resultEntity.getSelectColumns() + " FROM " + resultEntity.getTableName()));

		List<SqlNode> whereSqlNodes = new ArrayList<SqlNode>();
		List<Result> results = resultEntity.getResults();
		for (Result result : results) {
			if (result.isId()) whereSqlNodes.add(new StaticTextSqlNode(" and " + result.formatEqualsColumn()));
		}
		//where/if判断条件
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), new MixedSqlNode(whereSqlNodes)));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 查询
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode selectByPrimaryKeySelective(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//静态的sql部分:select column ... from table
		sqlNodes.add(new StaticTextSqlNode("SELECT " + resultEntity.getSelectColumns() + " FROM " + resultEntity.getTableName()));
		//where/if判断条件
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), getPrimaryKeyColumnNode(resultEntity)));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 查询总数
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode selectCount(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//select count(*) from table
		sqlNodes.add(new StaticTextSqlNode("SELECT COUNT(*) FROM " + resultEntity.getTableName()));
		//获取全部列的where,if条件
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), getAllIfColumnNode(resultEntity)));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 插入全部
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode insert(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//insert into table
		sqlNodes.add(new StaticTextSqlNode("INSERT INTO " + resultEntity.getTableName()));
		//插入全部的(列名,列名...)
		sqlNodes.add(new StaticTextSqlNode("(" + resultEntity.getInsertColumns() + ")"));

		List<SqlNode> ifNodes = new ArrayList<SqlNode>();
		//处理所有的values(属性值,属性值...)
		List<Result> results = resultEntity.getResults();
		for (Result column : results) {
			if (!column.isBefore()) continue;
			ifNodes.add(new StaticTextSqlNode(column.format() + ","));
		}
		//values(#{property},#{property}...)
		sqlNodes.add(new TrimSqlNode(ms.getConfiguration(), new MixedSqlNode(ifNodes), "VALUES (", null, ")", ","));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 插入不为null的字段
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode insertSelective(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//insert into table
		sqlNodes.add(new StaticTextSqlNode("INSERT INTO " + resultEntity.getTableName()));
		List<SqlNode> columns = new ArrayList<SqlNode>();
		List<SqlNode> values = new ArrayList<SqlNode>();

		//获取全部列
		List<Result> columnList = resultEntity.getResults();
		//处理values(#{property},#{property}...)
		//处理table(column,column...)
		for (Result column : columnList) {
			if (!column.isBefore()) continue;
			columns.add(getIfNotNull(column, new StaticTextSqlNode(column.getColumn() + ",")));
			values.add(getIfNotNull(column, new StaticTextSqlNode(column.format() + ",")));
		}

		//table(column,column...)
		sqlNodes.add(new TrimSqlNode(ms.getConfiguration(), new MixedSqlNode(columns), "(", null, ")", ","));
		//values(#{property},#{property}...)
		sqlNodes.add(new TrimSqlNode(ms.getConfiguration(), new MixedSqlNode(values), "VALUES (", null, ")", ","));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 通过条件删除
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode delete(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//delete from table
		sqlNodes.add(new StaticTextSqlNode("DELETE FROM " + resultEntity.getTableName()));
		//where/if判断条件
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), getAllIfColumnNode(resultEntity)));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 通过主键删除
	 *
	 * @param ms
	 */
	public SqlNode deleteByPrimaryKey(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//delete from table
		sqlNodes.add(new StaticTextSqlNode("DELETE FROM " + resultEntity.getTableName()));
		//where/if判断条件
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), getPrimaryKeyColumnNode(resultEntity)));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 通过主键更新全部字段
	 *
	 * @param ms
	 */
	public SqlNode updateByPrimaryKey(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());

		//获取全部列
		List<Result> columnList = resultEntity.getResults();
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//update table
		sqlNodes.add(new StaticTextSqlNode("UPDATE " + resultEntity.getTableName()));
		List<SqlNode> ifNodes = new ArrayList<SqlNode>();
		for (Result column : columnList) {
			if (!column.isId()) {
				ifNodes.add(new StaticTextSqlNode(column.formatEqualsColumn() + ", "));
			}
		}
		sqlNodes.add(new SetSqlNode(ms.getConfiguration(), new MixedSqlNode(ifNodes)));
		//where/if判断条件
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), getPrimaryKeyColumnNode(resultEntity)));
		return new MixedSqlNode(sqlNodes);
	}

	/**
	 * 通过主键更新不为null的字段
	 *
	 * @param ms
	 * @return
	 */
	public SqlNode updateByPrimaryKeySelective(MappedStatement ms) {
		ResultEntity resultEntity = super.getResultEntity(ms.getId());
		List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
		//update table
		sqlNodes.add(new StaticTextSqlNode("UPDATE " + resultEntity.getTableName()));
		//获取全部列
		List<Result> columnList = resultEntity.getResults();
		List<SqlNode> ifNodes = new ArrayList<SqlNode>();
		//全部的if property!=null and property!=''
		for (Result column : columnList) {
			if (!column.isId()) {
				ifNodes.add(getIfNotNull(column, new StaticTextSqlNode(column.formatEqualsColumn() + ", ")));
			}
		}

		sqlNodes.add(new SetSqlNode(ms.getConfiguration(), new MixedSqlNode(ifNodes)));
		//where/if判断条件
		sqlNodes.add(new WhereSqlNode(ms.getConfiguration(), getPrimaryKeyColumnNode(resultEntity)));
		return new MixedSqlNode(sqlNodes);
	}
}
